from dataclasses import dataclass
from typing import List, Optional
from PySide6.QtCore import QObject, Signal
import os
import tempfile
from config.settings import IMAGE_RECOGNITION, ENABLE_RESULT_IMAGE


@dataclass
class RecognitionResult:
    """识别结果数据类"""

    template_name: str
    confidence: float
    top_left: tuple
    bottom_right: tuple
    width: int
    height: int
    color_match: float = 0.0


class RecognitionModel(QObject):
    """识别模型类，管理所有数据状态"""

    # 信号定义
    data_changed = Signal()  # 数据变化信号

    def __init__(self):
        super().__init__()
        # 图像相关
        self.current_image_path: str = None
        self.screenshot_x: int = 0
        self.screenshot_y: int = 0
        self.screenshot_width: int = None
        self.screenshot_height: int = None

        # 识别相关
        self.recognition_results: List[RecognitionResult] = []
        self.current_method: str = "TM_CCORR_NORMED"
        self.match_threshold: float = IMAGE_RECOGNITION["default_threshold"]
        self.enable_print: bool = False
        self.enable_result_image: bool = ENABLE_RESULT_IMAGE

        # 临时文件管理
        self.temp_dir = os.path.join(tempfile.gettempdir(), "PySide6x")
        os.makedirs(self.temp_dir, exist_ok=True)

        # 模板管理
        self.template_checkboxes = []

    def update_image(self, image_path: str, x: int = 0, y: int = 0, width: int = None, height: int = None) -> None:
        """更新当前图像信息
        
        Args:
            image_path: 图像文件路径
            x: 截图区域左上角X坐标
            y: 截图区域左上角Y坐标
            width: 截图区域宽度
            height: 截图区域高度
        """
        self.current_image_path = image_path
        self.screenshot_x = x
        self.screenshot_y = y
        # 保存宽高信息以便重复使用
        if width is not None:
            self.screenshot_width = width
        if height is not None:
            self.screenshot_height = height
        self.data_changed.emit()

    def update_recognition_results(self, results: List[RecognitionResult]) -> None:
        """更新识别结果"""
        self.recognition_results = results
        self.data_changed.emit()

    def update_match_method(self, method: str) -> None:
        """更新匹配方法"""
        self.current_method = method
        self.data_changed.emit()

    def update_match_threshold(self, threshold: float) -> None:
        """更新匹配阈值"""
        self.match_threshold = threshold
        self.data_changed.emit()

    def update_result_image_mode(self, enable_result_image: bool) -> None:
        """更新结果图生成模式"""
        self.enable_result_image = enable_result_image
        self.data_changed.emit()

    def update_settings(self, method: str, threshold: float) -> None:
        """更新多个设置"""
        self.current_method = method
        self.match_threshold = threshold
        self.data_changed.emit()

    def get_active_templates(self) -> List[str]:
        """获取已启用的模板列表"""
        return [
            cb.property("target_image")
            for cb in self.template_checkboxes
            if cb.isChecked()
        ]

    def get_template_names(self) -> dict:
        """获取模板名称字典"""
        return {
            cb.property("target_image"): cb.property("target_label")
            for cb in self.template_checkboxes
            if cb.isChecked()
        }

    def cleanup(self) -> None:
        """清理临时文件"""
        if os.path.exists(self.temp_dir):
            for entry in os.scandir(self.temp_dir):
                if entry.is_file():
                    try:
                        os.unlink(entry.path)
                    except Exception as e:
                        print(f"无法删除文件 {entry.path}: {e}")
